import com.sun.deploy.security.CertUtils;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.x509.*;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Random;

public class BaseCert {

    static
    {
        Security.addProvider(new BouncyCastleProvider());
    }

    protected static KeyPairGenerator kpg=null;

    public BaseCert()
    {
        try
        {
            kpg=KeyPairGenerator.getInstance("RSA");
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
    }

    public X509Certificate generateCert(String user)
    {
        X509Certificate cert=null;
        try
        {
            // 设置开始日期和结束日期
            long year = 360 * 24 * 60 * 60 * 1000;
            Date notBefore = new Date();
            Date notAfter = new Date(notBefore.getTime() + year);
            // 设置颁发者和主题
            String issuerString = "CN=root,OU=单位,O=组织";
            X500Name issueDn = new X500Name(issuerString);
            X500Name subjectDn = new X500Name(issuerString);
            // 证书序列号
            BigInteger serail = BigInteger.probablePrime(32, new Random());
            //证书中的公钥
            KeyPair keyPair=this.kpg.generateKeyPair();
            PublicKey pubKey=keyPair.getPublic();
            PrivateKey priKey=keyPair.getPrivate();
            //组装公钥信息
            SubjectPublicKeyInfo subjectPublicKeyInfo = null;
            try {
                subjectPublicKeyInfo = SubjectPublicKeyInfo
                        .getInstance(new ASN1InputStream(pubKey.getEncoded())
                                .readObject());
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            //证书的签名数据
            final byte[] signatureData ;
            try {
                Signature signature = Signature.getInstance("SHA1withRSA");
                signature.initSign(priKey);
                signature.update(priKey.getEncoded());
                signatureData = signature.sign();
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(),e);
            }
            //组装证书
            X509v3CertificateBuilder builder = new X509v3CertificateBuilder(
                    issueDn, serail, notBefore, notAfter, subjectDn,
                    subjectPublicKeyInfo);
            //给证书签名
            X509CertificateHolder holder=builder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(priKey));
            try {
                byte[] certBuf = holder.getEncoded();
                X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(new ByteArrayInputStream(certBuf));
                System.out.println(certificate);
                //证书base64编码字符串
                System.out.println(Base64.encode(certificate.getEncoded()));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (CertificateException e) {
                e.printStackTrace();
            }
            return new JcaX509CertificateConverter().setProvider( "BC" )
                    .getCertificate( holder );
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return cert;
    }
}
